//
//  Square.m
//  INFSWA02
//
//  Created by Justin van Grootveld on 9/15/11.
//  Copyright 2011 Pro4all. All rights reserved.
//

#import "Square.h"
#import "Piece.h"
#import "Player.h"

@interface Square()
- (BOOL)doesSquaresHasPiece:(Square *)sqaure;
// - (BOOL)isInActionDirection:(Direction)direction rangeOfSquareWithPiece:(Square *)square;
@end

@implementation Square

@synthesize board = _board, location = _location, color = _color, button = _button;

- (id)initWithBoard:(Board *)board andLocation:(NSPoint)location
{
    self = [super init];
    if (self) 
    {
        _board = board;
        _location = location;
    }
    
    return self;
}

- (Piece *)piece;
{
    return _piece;
}

- (BOOL)setPiece:(Piece *)piece
{
    if(![self hasPiece])
    {
        _piece = piece;
        return YES;
    }
    
    return NO;
}

- (void)removePiece
{
    _piece = nil;
}

- (BOOL)hasPiece
{
    return (_piece) ? YES : NO;
}

- (BOOL)doesSquaresHasPiece:(Square *)sqaure
{
    if(![self hasPiece])
    {
        NSLog(@"This sqaure does not contain a piece.");
        return NO;
    }
    
    if(![sqaure hasPiece])
    {
        NSLog(@"Selected sqaure does not contain a piece.");
        return NO;
    }
    
    return YES;
}

- (BOOL)hasPieceOwnedByCurrentPlayer
{
    Player *player = [[self piece] player];
    Player *currentPlayer = [_board currentPlayer];
    
    if(player && currentPlayer)
    {
        return (player.identifier == currentPlayer.identifier);
    }
    
    return NO;
}

- (void)setButtonTitle
{
    NSString *title = @"";
    
    if ([self hasPiece])
        title = [_piece printCode];
    
    [_button setTitle:title];
}

//- (BOOL)isInActionDirection:(Direction)direction rangeOfSquareWithPiece:(Square *)square
//{
//    if([self doesSquaresHasPiece:square])
//    {
//        int x1 = self.location.x;
//        int y1 = self.location.y;
//        int x2 = [square location].x;
//        int y2 = [square location].y;
//        NSInteger range = [square piece].range;
//        
//        if(x1 == x2)                        //if squares are vertically aligned
//        {
//            if(abs(y1-y2) > range) return NO;   //if distance is to far
//            
//            if(y2 > y1)                         //if selected square is above own square
//            {
//                if([[square piece] containsDirection:TOP InDirection:direction]) //piece can do action in direction
//                {
//                    //hmm
//                    //mis beter method voor return squares to attack/move at.
//                }
//            }
//            else                                //if selected square is below own square
//            {
//                return [[square piece] containsDirection:BOTTOM InDirection:direction];
//            }
//        }
//        else if(y1 == y2)                   //if squares are horizontally aligned
//        {
//            if(abs(x1-x2) > range) return NO;   //if distance is to far
//            
//            if(x2 > x1)                         //if selected square is on the right side of own square
//            {
//                return [[square piece] containsDirection:RIGHT InDirection:direction];
//            }
//            else                                //if selected square is on the left side of own square
//            {
//                return [[square piece] containsDirection:LEFT InDirection:direction];
//            }
//        }
//        else if(abs(x1-y1) == abs(x2-y2))   //if squares are diagonally aligned from (bottomLeft to topRight)
//        {
//            if(abs(x1-x2) > range) return NO;   //if distance is to far
//            
//            if(x2 > x1)                         //if selected square is on the top-right side of own square
//            {
//                return [[square piece] containsDirection:TOPRIGHT InDirection:direction];
//            }
//            else                                //if selected square is on the bottom-left side of own square
//            {
//                return [[square piece] containsDirection:BOTTOMLEFT InDirection:direction];
//            }
//        }
//        else if(x1+y1 == x2+y2)             //if squares are diagonally aligned from (bottomRight to topLeft)
//        {
//            if(abs(x1-x2) > range) return NO;   //if distance is to far
//            
//            if(x2 > x1)                         //if selected square is on the bottom-right side of own square
//            {
//                return [[square piece] containsDirection:BOTTOMRIGHT InDirection:direction];
//            }
//            else                                //if own piece is on the top-left side of enemy piece
//            {
//                return [[square piece] containsDirection:TOPLEFT InDirection:direction];
//            }
//        }
//    }
//    
//    return NO;
//}

- (BOOL)isInMoveRangeOfSquareWithPiece:(Square *)square
{
   // return [self isInActionDirection:[self piece].moveDirection rangeOfSquareWithPiece:square];
    
    NSMutableArray *squares = [self squaresWhichCanBeMovedAt];
    
    for(Square *s in squares)
    {
        if(s == square) return YES;
    }
    
    return NO;
}

- (BOOL)isInAttackRangeOfSquareWithPiece:(Square *)square
{
   // return [self isInActionDirection:[self piece].attackDirection rangeOfSquareWithPiece:square];
    
    NSMutableArray *squares = [self squaresWhichCanBeAttacked];
    
    for(Square *s in squares)
    {
        if(s == square) return YES;
    }
    
    return NO;
}

- (NSMutableArray *)squaresWhichCanBeAttacked
{
    NSMutableArray *squares = nil;
    
    if([self hasPiece])
    {
        squares = [NSMutableArray new];
        Piece *piece = [self piece];
        NSInteger range = piece.range;
        int x1 = self.location.x;
        int y1 = self.location.y;
        int i = 0;
        
        if([piece containsDirection:TOP InDirection:piece.attackDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1 andY:y1+i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece] && ![square hasPieceOwnedByCurrentPlayer])
                {
                    [squares addObject:square];
                    if(!_piece.canAttackTroughAir) break; //if piece can't attack trough air he is blocked by the first enemy
                }
            }
        }
        
        if([piece containsDirection:BOTTOM InDirection:piece.attackDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1 andY:y1-i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece] && ![square hasPieceOwnedByCurrentPlayer])
                {
                    [squares addObject:square];
                    if(!_piece.canAttackTroughAir) break; //if piece can't attack trough air he is blocked by the first enemy
                }
            }
        }
        
        if([piece containsDirection:LEFT InDirection:piece.attackDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1-i andY:y1];
                
                if(!square) break;  //outside board
                
                if([square hasPiece] && ![square hasPieceOwnedByCurrentPlayer])
                {
                    [squares addObject:square];
                    if(!_piece.canAttackTroughAir) break; //if piece can't attack trough air he is blocked by the first enemy
                }
            }
        }
        
        if([piece containsDirection:RIGHT InDirection:piece.attackDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1+i andY:y1];
                
                if(!square) break;  //outside board
                
                if([square hasPiece] && ![square hasPieceOwnedByCurrentPlayer])
                {
                    [squares addObject:square];
                    if(!_piece.canAttackTroughAir) break; //if piece can't attack trough air he is blocked by the first enemy
                }
            }
        }
        
        if([piece containsDirection:TOPLEFT InDirection:piece.attackDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1-i andY:y1+i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece] && ![square hasPieceOwnedByCurrentPlayer])
                {
                    [squares addObject:square];
                    if(!_piece.canAttackTroughAir) break; //if piece can't attack trough air he is blocked by the first enemy
                }
            }
        }
        
        if([piece containsDirection:TOPRIGHT InDirection:piece.attackDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1+i andY:y1+i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece] && ![square hasPieceOwnedByCurrentPlayer])
                {
                    [squares addObject:square];
                    if(!_piece.canAttackTroughAir) break; //if piece can't attack trough air he is blocked by the first enemy
                }
            }
        }
        
        if([piece containsDirection:BOTTOMLEFT InDirection:piece.attackDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1-i andY:y1-i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece] && ![square hasPieceOwnedByCurrentPlayer])
                {
                    [squares addObject:square];
                    if(!_piece.canAttackTroughAir) break; //if piece can't attack trough air he is blocked by the first enemy
                }
            }
        }
        
        if([piece containsDirection:BOTTOMRIGHT InDirection:piece.attackDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1+i andY:y1-i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece] && ![square hasPieceOwnedByCurrentPlayer])
                {
                    [squares addObject:square];
                    if(!_piece.canAttackTroughAir) break; //if piece can't attack trough air he is blocked by the first enemy
                }
            }
        }
    }
    
    return squares;
}

- (NSMutableArray *)squaresWhichCanBeMovedAt
{
    NSMutableArray *squares = nil;
    
    if([self hasPiece])
    {
        squares = [NSMutableArray new];
        Piece *piece = [self piece];
        NSInteger range = piece.range;
        int x1 = self.location.x;
        int y1 = self.location.y;
        int i = 0;
        
        if([piece containsDirection:TOP InDirection:piece.moveDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1 andY:y1+i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece]) break; //can't walk trough enemy
                
                [squares addObject:square];
            }
        }
        
        if([piece containsDirection:BOTTOM InDirection:piece.moveDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1 andY:y1-i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece]) break; //can't walk trough enemy
                
                [squares addObject:square];
            }
        }
        
        if([piece containsDirection:LEFT InDirection:piece.moveDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1-i andY:y1];
                
                if(!square) break;  //outside board
                
                if([square hasPiece]) break; //can't walk trough enemy
                
                [squares addObject:square];
            }
        }
        
        if([piece containsDirection:RIGHT InDirection:piece.moveDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1+i andY:y1];
                
                if(!square) break;  //outside board
                
                if([square hasPiece]) break; //can't walk trough enemy
                
                [squares addObject:square];
            }
        }
        
        if([piece containsDirection:TOPLEFT InDirection:piece.moveDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1-i andY:y1+i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece]) break; //can't walk trough enemy
                
                [squares addObject:square];
            }
        }
        
        if([piece containsDirection:TOPRIGHT InDirection:piece.moveDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1+i andY:y1+i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece]) break; //can't walk trough enemy
                
                [squares addObject:square];
            }
        }
        
        if([piece containsDirection:BOTTOMLEFT InDirection:piece.moveDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1-i andY:y1-i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece]) break; //can't walk trough enemy
                
                [squares addObject:square];
            }
        }
        
        if([piece containsDirection:BOTTOMRIGHT InDirection:piece.moveDirection])
        {
            for(i = 1; i <= range; i++)
            {
                Square *square = [_board squareAtLocationX:x1+i andY:y1-i];
                
                if(!square) break;  //outside board
                
                if([square hasPiece]) break; //can't walk trough enemy
                
                [squares addObject:square];
            }
        }
    }
    
    return squares;
}

@end
